package com.sheng.project.study.genericity;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * @author liusheng
 * @date 2023/07/06
 */
public class Demo5<T1, T2> {
//    public static void main(String[] args) {
//        Demo5<String, Integer> demo5 = new Demo5<>();
//        demo5.m1(demo5);
//    }
//
//    public void m1(Demo5<T1, T2> demo) {
//        // m1 方法参数类型为 Demo5，在这个方法内部如果我们想获取这个参数具体的详细类型信息，
//        // 上面的代码是获取不到的，只能获取到 demo5 参数所属的类型是 Demo5，
//        // 但是无法获取到 Demo5 中的 T1 和 T2 这两个泛型变量类型对应的具体类型。
//        System.out.println(demo.getClass());
//    }

    // 根据 demo6 进行优化
    public static void main(String[] args) {
        Demo5<String, Integer> demo5 = new Demo5<String, Integer>() {
        };
        demo5.m1(demo5);
    }

    public void m1(Demo5<T1, T2> demo) {
        // demoClass 对应的是 Demo5 的 Class 对象
        Class<? extends Demo5> demoClass = demo.getClass();
        // 获取 Demo6 的父类的详细类型信息，包含泛型信息
        Type genericSuperclass = demoClass.getGenericSuperclass();
        // 泛型类型用 ParameterizedType 接口表示，输出看一下是不是这个接口类型的
        System.out.println(genericSuperclass.getClass());
        if (genericSuperclass instanceof ParameterizedType) {
            ParameterizedType pt = (ParameterizedType) genericSuperclass;
            System.out.println(pt.getRawType());
            Type[] actualTypeArguments = pt.getActualTypeArguments();
            for (Type actualTypeArgument : actualTypeArguments) {
                System.out.println(actualTypeArgument.getTypeName());
            }
            System.out.println(pt.getOwnerType());
        }
    }
}
